package cn.jcby.app.lebu.task;

import cn.jcby.app.lebu.dao.UserMotionPlanDao;
import cn.jcby.app.lebu.entity.UserMotionPlanEntity;
import cn.jcby.app.lebu.enums.CompleteTypeEnum;
import cn.jcby.app.lebu.enums.MessageTypeEnum;
import cn.jcby.app.lebu.enums.MotionTypeEnum;
import cn.jcby.app.lebu.service.UserMessageService;
import cn.jcby.app.lebu.service.UserMotionPlanService;
import cn.jcby.app.lebu.utils.LocalDateUtils;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/**
 * @author: lihaotian
 * @since: 2023/12/17 15:16
 * @description
 **/
//@EnableScheduling
@Component
public class MotionPlanStatusTask {

    static ConcurrentMap<String,UserMotionPlanEntity> map = new ConcurrentHashMap();
    @Autowired
    private UserMotionPlanDao userMotionPlanDao;
    @Autowired
    private UserMotionPlanService userMotionPlanService; ;
    @Autowired
    private UserMessageService userMessageService;

    @Value("${constants.auto.complete}")
    private Integer autoComplete;
    @Value("${constants.auto.close}")
    private Integer autoClose;

    //每5分钟检查一次，将超过计划时间半小时为启动的计划删除
    @Scheduled(cron = "0 0/5 * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void checkPlanStatus() {
        Date date = LocalDateUtils.addMinutes(new Date(),autoClose) ;
        List<UserMotionPlanEntity> list = userMotionPlanDao.selectList(Wrappers.<UserMotionPlanEntity>lambdaQuery()
                .eq(UserMotionPlanEntity::getStatus, 0)
                .lt(UserMotionPlanEntity::getBeginTime, date));
        //关闭
        if(CollectionUtils.isNotEmpty(list)){
            List<String> idList = list.stream().map(UserMotionPlanEntity::getId).collect(Collectors.toList());
            userMotionPlanDao.deleteByIdList(idList) ;
        }
    }

    //每8分钟检查一次，将室内和室外（初跑步、健走、骑行）进行中的超过预期的改为已完成
    @Scheduled(cron = "0 0/8 * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void checkPlanStatus2() {
        System.out.println("检查运动计划状态2");
        //一小时结束
        Date date = LocalDateUtils.addMinutes(new Date(),-autoComplete) ;
        List<UserMotionPlanEntity> list = userMotionPlanDao.selectList(Wrappers.<UserMotionPlanEntity>lambdaQuery()
                .isNotNull(UserMotionPlanEntity::getActualBeginTime)
                .eq(UserMotionPlanEntity::getStatus, 1)
                .lt(UserMotionPlanEntity::getActualBeginTime, date)
                .notIn(UserMotionPlanEntity::getMotionType,
                        MotionTypeEnum.RUN.getCode(),
                        MotionTypeEnum.BIKE.getCode(),
                        MotionTypeEnum.WALK.getCode())
        );

        if (CollectionUtils.isNotEmpty(list)){
            list.stream().forEach(e->{
                //map 避免重复处理
                if (map.containsKey(e.getId())){
                    return ;
                }
                map.put(e.getId(), e) ;
                //修改状态
                userMotionPlanDao.completePlan(e.getId(), CompleteTypeEnum.COMPLETE_NORMAL.getCode());
                //参与者消费金额，发起者及父级参与分销
                userMotionPlanService.completePlan(e) ;
                //推送消息
                userMessageService.addRecord(e.getParticipantUserId(),e.getUserId(), MessageTypeEnum.COMPLETE_REMIND,e.getEmerge().multiply(BigDecimal.valueOf(0.7)));
                map.remove(e.getId()) ;
            });
        }

    }

    //准备提醒，即计划开始前1小时提醒
    @Scheduled(cron = "0 0/2 * * *?")
    public void prepareRemind(){
        Date date = LocalDateUtils.addMinutes(new Date(),-autoComplete) ;
        List<UserMotionPlanEntity> list = userMotionPlanDao.selectList(Wrappers.<UserMotionPlanEntity>lambdaQuery()
                        .isNotNull(UserMotionPlanEntity::getParticipantUserId)
                .eq(UserMotionPlanEntity::getStatus, 0)
                .lt(UserMotionPlanEntity::getBeginTime, date)
        );
        if (CollectionUtils.isNotEmpty(list)){
            list.forEach(e->{
                userMessageService.addRecord(e.getParticipantUserId(),e.getUserId(), MessageTypeEnum.READY_REMIND);
                userMessageService.addRecord(e.getUserId(),e.getParticipantUserId(), MessageTypeEnum.READY_REMIND);
            });
        }
    }

}
